﻿using System;
using System.Collections.Generic;
using System.Text;
using Cwing.UI.Controls;
using System.ComponentModel;

using Cwing.UI.Validation.Manager;
using Cwing.UI.Validation;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Cwing.UI.Controls
{
    /// <summary>
    /// Customize Validation
    /// </summary>
    public class CustomizeValidation : IValidation
    {
        private static readonly Object CustomizeValidationValidatingCommand = new object();

        private static readonly Object CustomizeValidationValidateCommand = new object();

        private EventHandlerList Events = new EventHandlerList();

        /// <summary>
        /// Initial
        /// </summary>
        /// <param name="value">The value will be validated</param>
        /// <param name="messageContainer">Error Message Showing Control</param>
        public CustomizeValidation(String value, ErrorList messageContainer)
        {
            this.Value = value;
            this.errorList = messageContainer;
        }

        private Int32 index = 0;

        public int Index
        {
            get
            {
                return index;
            }
            set
            {
                index = value;
            }
        }

        /// <summary>
        /// Path of validation configuration in ValidationConfiguration.xml file
        /// <para>If Path is Null or Empty, this Validate will not be execute</para>
        /// </summary>
        public string Path
        {
            get;
            set;
        }

        /// <summary>
        /// The value will be validated
        /// </summary>
        public String Value
        {
            get;
            set;
        }

        /// <summary>
        /// Call this method to validated the value
        /// </summary>
        /// <returns></returns>
        public ValidationResult Validate()
        {
            if (IsValidate == false)
            {
                ValidationResult _result = ValidationResult.Empty;

                //Before Validate
                ValidatingEventArgs e = new ValidatingEventArgs();
                e.Cancel = false;
                e.Control = this;
                ValidationResult preValidationResult = OnControlValidating(e);
                if (e.Cancel)
                    return ValidationResult.Empty;

                if (!preValidationResult.IsEmpty && !preValidationResult.Result)
                {
                    result = preValidationResult;
                    return preValidationResult;
                }

                _result = new ControlValidationManager(Value, this).Validate();

                //After Validate
                ValidateEventArgs afterE = new ValidateEventArgs();
                afterE.Control = this;
                result = OnControlValidate(afterE, _result);

                IsValidate = true;
            }

            return result;
        }

        private ValidationResult result = ValidationResult.Empty;

        public ValidationResult ValidationResult
        {
            get { return result; }
            set
            {
                result = value;
            }
        }

        private Boolean isRendError = false;

        public Boolean IsRendError
        {
            get
            {
                return isRendError;
            }
            set
            {
                isRendError = value;
            }
        }

        private Boolean isValidate = false;

        public Boolean IsValidate
        {
            get
            {
                return isValidate;
            }
            set
            {
                isValidate = value;
            }
        }

        public string GroupName
        {
            get;
            set;
        }

        /// <summary>
        /// This property not implemented
        /// </summary>
        public string ValidationSummary
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        private ErrorList errorList = null;

        public ErrorList ErrorMessageContainer
        {
            get
            {
                return errorList;
            }
            set
            {
                errorList = value;
            }
        }

        private Configuration _configuration;

        public Configuration ValidationConfiguration
        {
            get
            {
                if (_configuration == null && !String.IsNullOrEmpty(Path))
                {
                    _configuration = ValidationConfigHelper.FetchConfigNode(Path);
                }

                return _configuration;
            }
        }

        public event ControlValidated Validated
        {
            add
            {
                Events.AddHandler(CustomizeValidationValidateCommand, value);
            }
            remove
            {
                Events.RemoveHandler(CustomizeValidationValidateCommand, value);
            }
        }

        public event ControlValidating Validating
        {
            add
            {
                Events.AddHandler(CustomizeValidationValidatingCommand, value);
            }
            remove
            {
                Events.RemoveHandler(CustomizeValidationValidatingCommand, value);
            }
        }

        private ValidationResult OnControlValidating(ValidatingEventArgs e)
        {
            ControlValidating hanlder = Events[CustomizeValidationValidatingCommand] as ControlValidating;
            ValidationResult preResult = ValidationResult.Empty;
            if (hanlder != null)
            {
                hanlder(e, preResult);
            }
            return preResult;
        }

        private ValidationResult OnControlValidate(ValidateEventArgs e, ValidationResult result)
        {
            ControlValidated hanlder = Events[CustomizeValidationValidateCommand] as ControlValidated;
            if (hanlder != null)
            {
                hanlder(e, result);
            }
            return result;
        }

        /// <summary>
        /// Readonly
        /// </summary>
        public ValidationType ValidationType
        {
            get
            {
                return ValidationType.Server;
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public WebControl Self
        {
            get
            {
                return null;
            }
        }

        public string ToClientScript()
        {
            return ToString();
        }
    }
}
